package com.gullmall.product.service.impl;

import com.baomidou.mybatisplus.core.conditions.update.UpdateWrapper;
import com.gullmall.common.constant.ProductConstant;
import com.gullmall.product.dao.AttrAttrgroupRelationDao;
import com.gullmall.product.dao.AttrGroupDao;
import com.gullmall.product.dao.CategoryDao;
import com.gullmall.product.entity.AttrAttrgroupRelationEntity;
import com.gullmall.product.entity.AttrGroupEntity;
import com.gullmall.product.entity.CategoryEntity;
import com.gullmall.product.service.CategoryService;
import com.gullmall.product.vo.AttrGroupRelationVo;
import com.gullmall.product.vo.AttrVo;
import org.apache.commons.lang.StringUtils;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.gullmall.common.utils.PageUtils;
import com.gullmall.common.utils.Query;

import com.gullmall.product.dao.AttrDao;
import com.gullmall.product.entity.AttrEntity;
import com.gullmall.product.service.AttrService;
import org.springframework.transaction.annotation.Transactional;
import org.w3c.dom.Attr;


@Service("attrService")
@Transactional
public class AttrServiceImpl extends ServiceImpl<AttrDao, AttrEntity> implements AttrService {

    @Autowired
    private AttrAttrgroupRelationDao attrAttrgroupRelationDao;
    @Autowired
    private AttrGroupDao attrGroupDao;
    @Autowired
    private CategoryDao categoryDao;
    @Autowired
    private CategoryService categoryService;


    @Override
    public PageUtils queryPage(Map<String, Object> params) {
        IPage<AttrEntity> page = this.page(
                new Query<AttrEntity>().getPage(params),
                new QueryWrapper<AttrEntity>()
        );

        return new PageUtils(page);
    }

    @Override
    public Boolean saveAttr(AttrVo attrVo) {
        AttrEntity attrEntity = new AttrEntity();
        //org.springframework.beans
        BeanUtils.copyProperties(attrVo, attrEntity);
        //保存到attr表
        this.save(attrEntity);
        if (attrVo.getAttrType() == ProductConstant.AttrEnum.ATTR_TYPE_BASE.getCode()) {//基本属性才有attrgroup
            //保存到attr_attrgroup_relation表
            AttrAttrgroupRelationEntity attrAttrgroupRelationEntity =
                    new AttrAttrgroupRelationEntity();
            attrAttrgroupRelationEntity.setAttrId(attrEntity.getAttrId());
            attrAttrgroupRelationEntity.setAttrGroupId(attrVo.getAttrGroupId());
            attrAttrgroupRelationDao.insert(attrAttrgroupRelationEntity);
        }
        return null;
    }

    @Override
    public PageUtils queryBasePage(Long categoryId, Map<String, Object> params, String attrType) {
        IPage<AttrEntity> page;
        QueryWrapper<AttrEntity> wrapper = new QueryWrapper<>();
        //equalsIgnoreCase忽略大小写
        wrapper.eq("attr_type", "base".equalsIgnoreCase(attrType) ? ProductConstant.AttrEnum.ATTR_TYPE_BASE.getCode() : ProductConstant.AttrEnum.ATTR_TYPE_SALE.getCode());
        String key = (String) params.get("key");
        if (!StringUtils.isEmpty(key)) {
            wrapper.like("attr_name", key);
        }
        if (categoryId != 0) {//等于0则查全部
            wrapper.eq("catelog_id", categoryId);
        }
        page = this.page(
                new Query<AttrEntity>().getPage(params),
                wrapper
        );
        PageUtils pageUtils = new PageUtils(page);
        List<AttrEntity> records = page.getRecords();

        List<AttrVo> attrVoList = records.stream().map((attrEntity) -> {
            AttrVo attrVo = new AttrVo();
            BeanUtils.copyProperties(attrEntity, attrVo);
            if (attrEntity.getAttrType() == ProductConstant.AttrEnum.ATTR_TYPE_BASE.getCode()) {//销售属性为0,销售属性没有分组
                //获取 分类 和 分组的名字
                //去冗余表中获取组id
                AttrAttrgroupRelationEntity attrAttrgroupRelationEntity =
                        attrAttrgroupRelationDao.selectOne(new QueryWrapper<AttrAttrgroupRelationEntity>()
                                .eq("attr_id", attrEntity.getAttrId()));

                if (attrAttrgroupRelationEntity != null && attrAttrgroupRelationEntity.getAttrGroupId() != null) {
                    //去AttrGroup表中获取组名称
                    AttrGroupEntity attrGroupEntity =
                            attrGroupDao.selectById(attrAttrgroupRelationEntity.getAttrGroupId());
                    if (attrGroupEntity != null && attrGroupEntity.getAttrGroupName() != null) {
                        attrVo.setGroupName(attrGroupEntity.getAttrGroupName());
                    }
                }
            }

            CategoryEntity categoryEntity = categoryDao.selectById(attrEntity.getCatelogId());
            if (categoryEntity != null && categoryEntity.getName() != null) {
                attrVo.setCatelogName(categoryEntity.getName());
            }
            return attrVo;
        }).collect(Collectors.toList());
        pageUtils.setList(attrVoList);
        return pageUtils;
    }


    @Override
    public AttrVo getAttrVo(Long attrId) {
        AttrVo attrVo = new AttrVo();
        //查询attr表
        AttrEntity attrEntity = this.getById(attrId);
        BeanUtils.copyProperties(attrEntity, attrVo);
        //销售属性无需查询attr_attrgroup_relation表
        if (attrVo.getAttrType() == ProductConstant.AttrEnum.ATTR_TYPE_BASE.getCode()) {
            //查询冗余表attr_attrgroup_relation表
            AttrAttrgroupRelationEntity attrAttrgroupRelationEntity =
                    attrAttrgroupRelationDao.selectOne(
                            new QueryWrapper<AttrAttrgroupRelationEntity>().eq("attr_id", attrId));
            if (attrAttrgroupRelationEntity != null && attrAttrgroupRelationEntity.getAttrGroupId() != null) {
                attrVo.setAttrGroupId(attrAttrgroupRelationEntity.getAttrGroupId());
                AttrGroupEntity attrGroupEntity = attrGroupDao.selectById(attrAttrgroupRelationEntity.getAttrGroupId());
                attrVo.setGroupName(attrGroupEntity.getAttrGroupName());
            }
        }
        if (attrVo != null && attrVo.getCatelogId() != null) {
            Long[] catalogPath = categoryService.findCatalogPath(attrVo.getCatelogId());
            attrVo.setCatelogPath(catalogPath);
        }
        return attrVo;
    }

    @Override
    public Boolean updateAttrVo(AttrVo attrVo) {
        AttrEntity attrEntity = new AttrEntity();
        BeanUtils.copyProperties(attrVo, attrEntity);
        //1,更新attr表
        this.updateById(attrEntity);
        //销售属性无需更新attr_attrgroup_relation表
        if (attrVo.getAttrType() == ProductConstant.AttrEnum.ATTR_TYPE_BASE.getCode()) {
            AttrAttrgroupRelationEntity attrAttrgroupRelationEntity = new AttrAttrgroupRelationEntity();
            BeanUtils.copyProperties(attrVo, attrAttrgroupRelationEntity);
            if (attrAttrgroupRelationEntity != null && attrAttrgroupRelationEntity.getAttrId() != null) {
                attrAttrgroupRelationDao.update(attrAttrgroupRelationEntity, new UpdateWrapper<AttrAttrgroupRelationEntity>().eq("attr_id", attrAttrgroupRelationEntity.getAttrId()));
            }
        }
        return null;
    }

    /**
     * 根据分组ID,查找关联的所有的基本属性
     * @param attrGroupId
     * @return
     */
    @Override
    public List<AttrEntity> getRelationAttr(Long attrGroupId) {
        //因为是去attr_AttrGroup_Relation表中查,销售属性不会放入该表
        List<AttrAttrgroupRelationEntity> attrAttrGroupRelationEntities = attrAttrgroupRelationDao.selectList(
                new QueryWrapper<AttrAttrgroupRelationEntity>().eq("attr_group_id", attrGroupId));

        List<Long> attrIds =
                attrAttrGroupRelationEntities.stream().map(entity -> entity.getAttrId()).collect(Collectors.toList());
        if (attrIds.size() > 0) {
            return this.listByIds(attrIds);
        }
        return null;
    }

    @Override
    public void deleteRelation(List<AttrGroupRelationVo> attrGroupRelationVoList) {
        /*
        自定义SQL格式: 需要动态拼接or
        delete from 表名where
                (attrId="attrId" and attrGroupId="attrGroupId")
        or
                (attrId="attrId" and attrGroupId="attrGroupId")
        or .....;*/
        attrAttrgroupRelationDao.deleteBatchRelation(attrGroupRelationVoList);
    }

    @Override
    public void removeAttr(List<Long> attrIds) {
        this.removeBatchByIds(attrIds);
        attrAttrgroupRelationDao.removeAttr(attrIds);
    }

    @Override
    public PageUtils getNoRelationAttr(Long attrGroupId, Map<String, Object> params) {
        //1,当前分组只能关联自己所属分类下的属性
        AttrGroupEntity attrGroupEntity = attrGroupDao.selectById(attrGroupId);
        //当前分组所属的分类id
        Long catelogId = attrGroupEntity.getCatelogId();
        //2,所有分类是catelogId的属性,且attr_type为1(基本属性)
        List<AttrEntity> attrEntites = this.list(new QueryWrapper<AttrEntity>().eq("catelog_id", catelogId).eq("attr_type", ProductConstant.AttrEnum.ATTR_TYPE_BASE.getCode()));
        //获取attr_id
        List<Long> attrIds = attrEntites.stream().map(entity -> entity.getAttrId()).collect(Collectors.toList());
        if (attrIds != null && attrIds.size() > 0) {
            //2.1查询pms_attr_attrgroup_relation表中group_id为null的,且范围是attrids
            List<AttrAttrgroupRelationEntity> attrAttrgroupRelationEntities = attrAttrgroupRelationDao.selectList(new QueryWrapper<AttrAttrgroupRelationEntity>().in("attr_id", attrIds).isNull("attr_group_id"));
            //获取复合条件的attr_id
            List<Long> relationAttrIds = attrAttrgroupRelationEntities.stream().map(r -> r.getAttrId()).collect(Collectors.toList());
            //2.2再次查询attr表,带上分页或查询条件
            if (relationAttrIds != null && relationAttrIds.size() > 0) {
                QueryWrapper<AttrEntity> wrapper = new QueryWrapper<>();
                String key = (String) params.get("key");
                if (!StringUtils.isEmpty(key)) {
                    wrapper.eq("attr_id", key).or().like("attr_name", key);
                }
                wrapper.in("attr_id", relationAttrIds);
                IPage<AttrEntity> page = this.page(
                        new Query<AttrEntity>().getPage(params),
                        wrapper
                );
                return new PageUtils(page);
            }
        }
        return null;
    }

    //获取允许被搜索的属性的id
    @Override
    public List<Long> selectSearchAttrIds(List<Long> attrIds) {
        List<AttrEntity> attrEntities = this.listByIds(attrIds);
        //0,不能被检索.1,可以被检索
        List<Long> allowSearchAttrIds = attrEntities.stream()
                .filter(f -> f.getSearchType() == ProductConstant.AttrSearchStatusEnum.SEARCH.getCode())
                .map(m -> m.getAttrId()).collect(Collectors.toList());
        return allowSearchAttrIds;
    }
}